package entity;

import database.DBO;
import widget.DataTable;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.*;
import java.util.*;

/**
 * Created by LLAP on 2017/12/25.
 * Copyright (c) 2017 LLAP. All rights reserved.
 */
public abstract class Entity extends DefaultTableModel {
    protected String[] columns;
    protected String tableName;
    protected ArrayList<Integer> editedIndex = new ArrayList<>();
    protected ResultSet dataSource;
    protected ResultSetMetaData metaData;
    public abstract boolean isCellEditable(int row, int column);
    public Entity(String tableName, String[] columns) {
        this.columns = columns;
        this.tableName = tableName;
        for (String i : columns) {
            this.addColumn(i);
        }
    }
    public void setDataSource(ResultSet r) {
        try {
            ResultSet source = r;
            if (source == null) source = this.getData();
            dataSource = source;
            metaData = dataSource.getMetaData();
        }
        catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage());
        }
    }
    public void setValueAt(Object aValue, int row, int column) {
        super.setValueAt(aValue, row, column);
        int i, count = editedIndex.size();
        if (count == 0) editedIndex.add(row);
        else {
            for (i = 0; i < count; i++) {
                if (editedIndex.get(i) > row) {
                    editedIndex.add(i + 1, row);
                    break;
                }
            }
            if (i >= count) editedIndex.add(row);
        }
    }
    public ResultSet getData() {
        ResultSet ret = null;
        try {
            database.DBO db = new database.DBO();
            ret = db.findAll(tableName);
        }
        catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage());
        }
        return ret;
    }
    public void addData() {
        LinkedList<String> columnSet = new LinkedList<>();
        try {
            while (dataSource.next()) {
                for (int i = 0; i < columns.length; i++) {
                    columnSet.add(dataSource.getString(i + 1));
                }
                this.addRow(columnSet.toArray());
                columnSet.clear();
            }
        }
        catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage());
        }
    }
    public void clear() {
        while (this.getRowCount() > 0) {
            this.removeRow(0);
        }
    }
    public void refresh() {
        this.clear();
        dataSource = this.getData();
        this.addData();

    }
    public int removeData(Object[] keys) {
        int ret = 0;
        try {
            DBO db = new DBO();
            ret = db.delete(dataSource.getMetaData().getColumnName(1), keys, tableName);
            db.close();
        }
        catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage());
        }
        return ret;
    }
    public void updateData(Object[] values) {
        try {
            Object[] condition = new Object[]{
                    metaData.getColumnName(1) + " = ?",
                    values[0]
            };
            HashMap<String, Object> kvSet = new HashMap<>();
            for (int i = 2; i <= metaData.getColumnCount(); i++) {
                kvSet.put(metaData.getColumnName(i), values[i - 1]);
            }
            DBO db = new DBO();
            db.update(condition, tableName, kvSet);
            db.close();
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    public void add() {}
    public void search() {}
    public String[] getColumns() {
        return columns;
    }
    public ArrayList<Integer> getEditedIndex() {
        return editedIndex;
    }
}
